#include "stdafx.h"
#include "BTManager.h"

BTManager * BTManager::instance = NULL;

static GUID service_guid = { 0x5fc2a42e, 0x144e, 0x4bb5, { 0xb4, 0x3f, 0x4e, 0x61, 0x71, 0x1d, 0x1c, 0x32 } };

BTManager::BTManager()
{
}

BTManager::~BTManager()
{
	instance = NULL;
}

BTManager * BTManager::GetInstance()
{
	if (instance == NULL)
	{
		instance = new BTManager();
	}
	return instance;
}

void BTManager::OnDataReceived( void *p_data, UINT16 len )
{

}

void BTManager::OnEventReceived( UINT32 event_code )
{

}

BOOL BTManager::Init( BOOL isServer )
{
	PORT_RETURN_CODE port_rc;
	CString status;
	m_isServer = isServer;
	m_service_name = L"Widcomm SDK RFComm Service";

	// If we are a Chat Server create the service record.  If
	// it fails then get out now.
	//
	if ( m_isServer && ! DoCreateServiceRecord())
		return FALSE;

	// Set the security level.
	//
	UINT8 sec_level = BTM_SEC_NONE;

	if (! m_RfCommIf.SetSecurityLevel(m_service_name.GetBuffer(m_service_name.GetLength()), sec_level , m_isServer))
	{
// 		CString error;
// 		error.Format(IDS_SET_SECURITY_FAILED);
// 		SetDlgItemText(IDC_STATUS_TEXT, error);
		return FALSE;
	}

	// Depending on our mode open the port
	// 
	if ( m_isServer )
	{
		// Open the RFCOMM port as a server using the SCN acquired from
		// service creation.  Note, a second argument could be provided 
		// to indicate the desired MTU. In this case we have elected to
		// take the default (RFCOMM_DEFAULT_MTU).
		// 
		port_rc = OpenServer(m_RfCommIf.GetScn());

		status.Format(L"Port open, wait for client on SCN %d", m_RfCommIf.GetScn());
	}
	else
	{
		// Open the RFCOMM port as a client using the SCN acquired from
		// service discovery and the chosen device address.  Note, a third
		// argument could be provided to indicate the desired MTU. In this
		// case we have elected to take the default (RFCOMM_DEFAULT_MTU).
		//
		port_rc = OpenClient(m_RfCommIf.GetScn(), m_BdAddr);
		status.Format(L"Port opened on SCN %d", m_RfCommIf.GetScn());
	}

	if (SUCCESS != port_rc)
	{
// 		CString error;
// 		error.Format(IDS_PORT_OPEN_FAILED, port_rc);
// 		SetDlgItemText(IDC_STATUS_TEXT, error);
		return FALSE;
	}

//	SetDlgItemText(IDC_STATUS_TEXT, status);

	// Set text on button and flag to redefine it as the
	// way to stop an active session.
	//
//	SetDlgItemText(IDC_START_BUTTON, m_stop_session);

//	m_ServerCheck.EnableWindow( FALSE );

	m_isSessionStarted = TRUE;
	return TRUE;
}

BOOL BTManager::DoCreateServiceRecord()
{
	SDP_RETURN_CODE sdp_rc;
	CString error;

	// Assign a SCN for the service.
	//
	if ( ! m_RfCommIf.AssignScnValue(&service_guid))
	{
// 		CString error;
// 		error.Format(IDS_SCN_ASSIGN_FAILED);
// 		SetDlgItemText(IDC_STATUS_TEXT, error);
		return FALSE;
	}

	// Create a SDP Service object.
	//
	if (m_pSdpService)
		delete m_pSdpService;

	m_pSdpService = new CSdpService();

	// Create a service record in the database and add the
	// sequence to that record.
	//
	sdp_rc = m_pSdpService->AddServiceClassIdList (1, &service_guid);

	if ( SDP_OK != sdp_rc )
	{
// 		error.Format(_T("AddServiceClassIdList() failed, error code %i"), sdp_rc);
// 		SetDlgItemText(IDC_STATUS_TEXT, error);
		return FALSE;
	}

	// Add Service Name attribute to the service record.
	//
	sdp_rc = m_pSdpService->AddServiceName (m_service_name.GetBuffer(m_service_name.GetLength()));

	if ( SDP_OK != sdp_rc )
	{
// 		error.Format(_T("AddServiceName() failed, error code %i"), sdp_rc);
// 		SetDlgItemText(IDC_STATUS_TEXT, error);
		return FALSE;
	}

	// Add the protocol descriptor.
	//
	sdp_rc = m_pSdpService->AddRFCommProtocolDescriptor(m_RfCommIf.GetScn());

	if ( SDP_OK != sdp_rc )
	{
// 		error.Format(_T("AddRFCommProtocolDescriptor() failed, error code %i"), sdp_rc);
// 		SetDlgItemText(IDC_STATUS_TEXT, error);
		return FALSE;
	}

//	TestAddAdditionalProtocol();

	// Make service browsable.
	//
	sdp_rc = m_pSdpService->MakePublicBrowseable();

	if ( SDP_OK != sdp_rc )
	{
// 		error.Format(_T("MakePublicBrowseable() failed, error code %i"), sdp_rc);
// 		SetDlgItemText(IDC_STATUS_TEXT, error);
		return FALSE;
	}

	return TRUE;
}

void BTManager::Stop()
{
	// Close the RFCOMM port.
	//
	PORT_RETURN_CODE port_rc = Close();

	if (SUCCESS != port_rc && NOT_OPENED != port_rc)
	{
// 		CString error;
// 		error.Format(_T("Chat Port close failed,, error code %i"), port_rc);
// 		SetDlgItemText(IDC_STATUS_TEXT, error);
	}

	// Set text on button and flag to redefine it as the
	// way to restart a session.
	//
	//SetDlgItemText(IDC_START_BUTTON, m_start_session);

	// Disable things.
	//
// 	m_SendButton.EnableWindow( FALSE );
// 	m_NewLineEdit.EnableWindow( FALSE );
// 	m_DsrDtrButton.EnableWindow( FALSE );
// 	m_CtsRtsButton.EnableWindow( FALSE );

	// It should now be possible to change from Client
	// mode to Server, and vice-versa.
	//
//	m_ServerCheck.EnableWindow( TRUE );

	// Delete the SDP object (if created).  This
	// removes the service from the 'available' list.
	//
	if (m_pSdpService)
	{
		delete m_pSdpService;
		m_pSdpService = NULL;
	}

	m_isSessionStarted = FALSE;
}

void BTManager::Send() 
{
	PORT_RETURN_CODE port_rc;
	CString text;

// 	GetDlgItemText(IDC_NEWLINE_EDIT, text);

	unsigned short length_written;
	LPCTSTR msg_to_send = (LPCTSTR) text;

	char *cMessage = new char[text.GetLength()];


	//jtm
	//accepter wants char *
	wcstombs(cMessage, text, text.GetLength());
	port_rc = Write( (void *) cMessage, text.GetLength(), &length_written);
	delete []cMessage;
	if (SUCCESS != port_rc)
	{
// 		CString error;
// 		error.Format(_T("Write failed, with code %i"), port_rc);
// 		AddLogText(error);
	}
	else
	{
// 		AddLogText(_T(">> ") + text);
// 		// clear out the edit line for the next messages to be sent
// 		SetDlgItemText(IDC_NEWLINE_EDIT, _T(""));
// 		CEdit* pEdit = (CEdit*)GetDlgItem(IDC_NEWLINE_EDIT);
// 		pEdit->SetFocus();
	}
}
